package com.gitee.deeround.jdbchelper.core;

import com.gitee.deeround.jdbchelper.out.DataTable;
import com.gitee.deeround.jdbchelper.out.PageList;
import com.gitee.deeround.jdbchelper.resultSetExtractors.CustomApply;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * 数据库查询
 *
 * @author deeround
 * @date 2024/03/29
 */
public interface DbActionQuery {


    //================queryForDataTable===================

    /**
     * 查询DataTable
     *
     * @param sql SQL
     * @return 返回DataTable
     */
    DataTable queryForDataTable(String sql);

    /**
     * 查询DataTable
     *
     * @param sql  SQL
     * @param args 参数
     * @return 返回DataTable
     */
    DataTable queryForDataTable(String sql, Object[] args);


    //================queryForList===================

    /**
     * 查询Map集合
     *
     * @param sql SQL
     * @return 返回Map集合
     */
    List<Map<String, Object>> queryForList(String sql);

    /**
     * 查询Map集合
     *
     * @param sql  SQL
     * @param args 参数
     * @return 返回Map集合
     */
    List<Map<String, Object>> queryForList(String sql, Object[] args);

    /**
     * 查询对象集合
     *
     * @param sql         SQL
     * @param elementType 元素类型
     * @return 返回对象集合
     */
    <T> List<T> queryForListObject(String sql, Class<T> elementType);

    /**
     * 查询对象集合
     *
     * @param sql         SQL
     * @param args        参数
     * @param elementType 元素类型
     * @return 返回对象集合
     */
    <T> List<T> queryForListObject(String sql, Object[] args, Class<T> elementType);

    /**
     * 查询对象集合
     *
     * @param sql         SQL
     * @param customApply 自定义类型转换实现
     * @return 返回对象集合
     */
    <T> List<T> queryForListObject(String sql, CustomApply<T> customApply);

    /**
     * 查询对象集合
     *
     * @param sql         SQL
     * @param args        参数
     * @param customApply 自定义类型转换实现
     * @return 返回对象集合
     */
    <T> List<T> queryForListObject(String sql, Object[] args, CustomApply<T> customApply);


    //================queryForObject（只取第一行数据）===================

    /**
     * 查询Map（第一行数据）
     *
     * @param sql SQL
     * @return 第一行数据
     */
    Map queryForMap(String sql);

    /**
     * 查询Map（第一行数据）
     *
     * @param sql  SQL
     * @param args 参数
     * @return 第一行数据
     */
    Map queryForMap(String sql, Object[] args);

    /**
     * 查询对象（第一行数据）
     *
     * @param sql         SQL
     * @param elementType 元素类型
     * @return 第一行数据
     */
    <T> T queryForObject(String sql, Class<T> elementType);

    /**
     * 查询对象（第一行数据）
     *
     * @param sql         SQL
     * @param args        参数
     * @param elementType 元素类型
     * @return 第一行数据
     */
    <T> T queryForObject(String sql, Object[] args, Class<T> elementType);

    /**
     * 查询对象（第一行数据）
     *
     * @param sql         SQL
     * @param customApply 自定义类型转换实现
     * @return 第一行数据
     */
    <T> T queryForObject(String sql, CustomApply<T> customApply);

    /**
     * 查询对象（第一行数据）
     *
     * @param sql         SQL
     * @param args        参数
     * @param customApply 自定义类型转换实现
     * @return 第一行数据
     */
    <T> T queryForObject(String sql, Object[] args, CustomApply<T> customApply);


    //================queryForValue(只取第一行第一列的值，无数据为null)===================

    /**
     * 查询值
     *
     * @param sql sql
     * @return {@link Object}
     */
    Object queryForValue(String sql);

    /**
     * 查询值
     *
     * @param sql  sql
     * @param args 参数
     * @return {@link Object}
     */
    Object queryForValue(String sql, Object[] args);

    /**
     * 字符串查询
     *
     * @param sql sql
     * @return {@link String}
     */
    String queryForString(String sql);

    /**
     * 字符串查询
     *
     * @param sql  sql
     * @param args 参数
     * @return {@link String}
     */
    String queryForString(String sql, Object[] args);

    /**
     * 查询整数
     *
     * @param sql sql
     * @return {@link Integer}
     */
    Integer queryForInteger(String sql);

    /**
     * 查询整数
     *
     * @param sql  sql
     * @param args 参数
     * @return {@link Integer}
     */
    Integer queryForInteger(String sql, Object[] args);

    /**
     * 查询小数
     *
     * @param sql sql
     * @return {@link BigDecimal}
     */
    BigDecimal queryForDecimal(String sql);

    /**
     * 查询小数
     *
     * @param sql  sql
     * @param args 参数
     * @return {@link BigDecimal}
     */
    BigDecimal queryForDecimal(String sql, Object[] args);


    //================queryForPage===================

    /**
     * 分页查询
     *
     * @param sql      SQL
     * @param pageNum  页码(从1开始)
     * @param pageSize 页大小
     * @return 返回Map集合
     */
    PageList<Map<String, Object>> queryForPage(String sql, int pageNum, int pageSize);

    /**
     * 分页查询
     *
     * @param sql      SQL
     * @param args     参数
     * @param pageNum  页码(从1开始)
     * @param pageSize 页大小
     * @return 返回Map集合
     */
    PageList<Map<String, Object>> queryForPage(String sql, Object[] args, int pageNum, int pageSize);

    /**
     * 分页查询
     *
     * @param sql         SQL
     * @param pageNum     页码(从1开始)
     * @param pageSize    页大小
     * @param elementType 元素类型
     * @return 返回对象集合
     */
    <T> PageList<T> queryForPage(String sql, int pageNum, int pageSize, Class<T> elementType);

    /**
     * 分页查询
     *
     * @param sql         SQL
     * @param args        参数
     * @param pageNum     页码(从1开始)
     * @param pageSize    页大小
     * @param elementType 元素类型
     * @return 返回对象集合
     */
    <T> PageList<T> queryForPage(String sql, Object[] args, int pageNum, int pageSize, Class<T> elementType);

    /**
     * 分页查询
     *
     * @param sql         SQL
     * @param pageNum     页码(从1开始)
     * @param pageSize    页大小
     * @param customApply 自定义类型转换实现
     * @return 返回对象集合
     */
    <T> PageList<T> queryForPage(String sql, int pageNum, int pageSize, CustomApply<T> customApply);

    /**
     * 分页查询
     *
     * @param sql         SQL
     * @param args        参数
     * @param pageNum     页码(从1开始)
     * @param pageSize    页大小
     * @param customApply 自定义类型转换实现
     * @return 返回对象集合
     */
    <T> PageList<T> queryForPage(String sql, Object[] args, int pageNum, int pageSize, CustomApply<T> customApply);

    /**
     * 获取分页SQL语句
     *
     * @param sql      sql
     * @param pageNum  页码(从1开始)
     * @param pageSize 页大小
     * @return {@link String}
     */
    String getPageSql(String sql, int pageNum, int pageSize);

}
